<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>ES6 新增用法 ( 四 ) | Saturday_</title><meta name="keywords" content="js,javascript,ES6,数组去重"><meta name="author" content="HHR"><meta name="copyright" content="HHR"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="Iterator 遍历器for…of 为什么不遍历 object 对象要想能够被 for...of 正常遍历的 , 都需要实现一个遍历器 Iterator , 而数组 , Set 和 Map 结构 , 早就内置好了遍历器 Iterator ( 又叫迭代器 ) , 它们的原型中都有一个 Symbol.iterator 方法 : 而 Object 对象并没有实现这个接口 , 使得它无法被 for...">
<meta property="og:type" content="article">
<meta property="og:title" content="ES6 新增用法 ( 四 )">
<meta property="og:url" content="https://codehhr.cn/2021/06/24/js/es6-day04/index.html">
<meta property="og:site_name" content="Saturday_">
<meta property="og:description" content="Iterator 遍历器for…of 为什么不遍历 object 对象要想能够被 for...of 正常遍历的 , 都需要实现一个遍历器 Iterator , 而数组 , Set 和 Map 结构 , 早就内置好了遍历器 Iterator ( 又叫迭代器 ) , 它们的原型中都有一个 Symbol.iterator 方法 : 而 Object 对象并没有实现这个接口 , 使得它无法被 for...">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://codehhr.coding.net/p/codehhr/d/wallpaper/git/raw/master/desktop.png">
<meta property="article:published_time" content="2021-06-24T13:06:25.000Z">
<meta property="article:modified_time" content="2021-06-25T09:06:29.066Z">
<meta property="article:author" content="HHR">
<meta property="article:tag" content="js">
<meta property="article:tag" content="javascript">
<meta property="article:tag" content="ES6">
<meta property="article:tag" content="数组去重">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://codehhr.coding.net/p/codehhr/d/wallpaper/git/raw/master/desktop.png"><link rel="shortcut icon" href="/img/favicon.ico"><link rel="canonical" href="https://codehhr.cn/2021/06/24/js/es6-day04/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"search.xml","languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"简"},
  noticeOutdate: {"limitDay":680,"position":"top","messagePrev":"It has been","messageNext":"days since the last update, the content of the article may be outdated."},
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: true,
    post: false
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: {"limitCount":50,"languages":{"author":"作者: HHR","link":"链接: ","source":"来源: Saturday_","info":"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},
  lightbox: 'fancybox',
  Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#49b1f5","bgDark":"#121212","position":"top-center"},
  source: {
    jQuery: 'https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js',
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/js/jquery.justifiedGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/css/justifiedGallery.min.css'
    },
    fancybox: {
      js: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.js',
      css: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: true,
  isanchor: true
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'ES6 新增用法 ( 四 )',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2021-06-25 17:06:29'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const fontSizeVal = saveToLocal.get('global-font-size')
    if (fontSizeVal !== undefined) {
      document.documentElement.style.setProperty('--global-font-size', fontSizeVal + 'px')
    }
    
    const detectApple = () => {
      if (GLOBAL_CONFIG_SITE.isHome && /iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><script src="/js/jquery.min.js"></script><link rel="stylesheet" href="/css/cursor.css"><link rel="stylesheet" href="/css/footergradient.css"><link rel="stylesheet" href="/css/scrollbar.css"><link rel="stylesheet" href="/css/animate.min.css"><meta name="generator" content="Hexo 5.4.0"><link rel="alternate" href="/atom.xml" title="Saturday_" type="application/atom+xml">
</head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "" data-lazy-src="https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg" onerror="onerror=null;src='https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg'" alt="avatar"/></div><div class="site-data"><div class="data-item is-center"><div class="data-item-link"><a href="/archives/"><div class="headline">文章</div><div class="length-num">87</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/tags/"><div class="headline">标签</div><div class="length-num">120</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/categories/"><div class="headline">分类</div><div class="length-num">31</div></a></div></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="javascript:void(0);"><i class="fa-fw fas fa-image"></i><span> 照片</span><i class="fas fa-chevron-down expand"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/school/"><i class="fa-fw fas fa-graduation-cap"></i><span> 科大</span></a></li><li><a class="site-page child" href="/wallpaper/"><i class="fa-fw fas fa-image"></i><span> 壁纸</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div><div class="menus_item"><a class="site-page" href="/messageboard/"><i class="fa-fw fas fa-paper-plane"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="javascript:void(0);"><i class="fa-fw fa fa-list"></i><span> 娱乐</span><i class="fas fa-chevron-down expand"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/music/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li></ul></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://codehhr.coding.net/p/codehhr/d/images/git/raw/master/csslayouts/sunrise.jpg')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">Saturday_</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="javascript:void(0);"><i class="fa-fw fas fa-image"></i><span> 照片</span><i class="fas fa-chevron-down expand"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/school/"><i class="fa-fw fas fa-graduation-cap"></i><span> 科大</span></a></li><li><a class="site-page child" href="/wallpaper/"><i class="fa-fw fas fa-image"></i><span> 壁纸</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div><div class="menus_item"><a class="site-page" href="/messageboard/"><i class="fa-fw fas fa-paper-plane"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="javascript:void(0);"><i class="fa-fw fa fa-list"></i><span> 娱乐</span><i class="fas fa-chevron-down expand"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/music/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li></ul></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">ES6 新增用法 ( 四 )</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2021-06-24T13:06:25.000Z" title="发表于 2021-06-24 21:06:25">2021-06-24</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2021-06-25T09:06:29.066Z" title="更新于 2021-06-25 17:06:29">2021-06-25</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/js/">js</a><i class="fas fa-angle-right post-meta-separator"></i><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/js/ES6/">ES6</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">3.9k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>16分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="ES6 新增用法 ( 四 )"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="Iterator-遍历器"><a href="#Iterator-遍历器" class="headerlink" title="Iterator 遍历器"></a>Iterator 遍历器</h1><h2 id="for…of-为什么不遍历-object-对象"><a href="#for…of-为什么不遍历-object-对象" class="headerlink" title="for…of 为什么不遍历 object 对象"></a>for…of 为什么不遍历 object 对象</h2><p>要想能够被 <code>for...of</code> 正常遍历的 , 都需要实现一个遍历器 <code>Iterator</code> , 而数组 , <code>Set</code> 和 <code>Map</code> 结构 , 早就内置好了遍历器 <code>Iterator</code> ( 又叫迭代器 ) , 它们的原型中都有一个 <code>Symbol.iterator</code> 方法 : 而 <code>Object</code> 对象并没有实现这个接口 , 使得它无法被 <code>for...of</code> 遍历</p>
<p>验证一下 , 它们的原型中到底是不是有个叫 <code>Symbol.iterator</code> 的方法:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//数组</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="built_in">Array</span>.prototype[<span class="built_in">Symbol</span>.iterator]); <span class="comment">//结果 : function values()&#123;...&#125;</span></span><br><span class="line"><span class="comment">//字符串</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="built_in">String</span>.prototype[<span class="built_in">Symbol</span>.iterator]); <span class="comment">//结果 : function [Symbol.iterator]()&#123;...&#125;</span></span><br><span class="line"><span class="comment">//Set结构</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="built_in">Set</span>.prototype[<span class="built_in">Symbol</span>.iterator]); <span class="comment">//结果 : function values()&#123;...&#125;</span></span><br><span class="line"><span class="comment">//Map结构</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="built_in">Map</span>.prototype[<span class="built_in">Symbol</span>.iterator]); <span class="comment">//结果 : function entries()&#123;...&#125;</span></span><br><span class="line"><span class="comment">//Object对象</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="built_in">Object</span>.prototype[<span class="built_in">Symbol</span>.iterator]); <span class="comment">// undefined</span></span><br></pre></td></tr></table></figure>

<p>唯独 <code>Object</code> 对象的原型上没有 <code>Symbol.iterator</code> , 返回了 : <code>undefined</code> , 其他的数据类型的原型上都含有一个名字叫 <code>Symbol.iterator</code> 的方法</p>
<p><strong>注意</strong> : <code>Symbol.iterator</code> 是 <code>Symbol</code> 对象的 <code>iterator</code> 属性 , 是一个特殊的 <code>Symbol</code> 值 , 因此 , 当它作为 <code>prototype</code> 对象属性名的时候 , 获取它的时候需要使用 <code>[]</code> 的形式: <code>prototype[Symbol.iterator]</code> , 不能使用点形式获取 : prototype.Symbol.iterator<br>也就说 , 只要一个数据结构拥有一个叫 <code>[Symbol.iterator]()</code> 方法的数据结构 , 就可以被 <code>for...of</code> 遍历</p>
<h2 id="Iterator-原理"><a href="#Iterator-原理" class="headerlink" title="Iterator 原理"></a>Iterator 原理</h2><p>当可遍历对象被 <code>for...of</code> 遍历的时候 , <code>[Symbol.iterator]()</code> 就会被调用 , 返回一个 <code>iterator</code> 对象 , <code>iterator</code> 对象里有一个很重要的方法 : <code>next()</code></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> arr = [<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>, <span class="string">&quot;c&quot;</span>];</span><br><span class="line"><span class="keyword">let</span> iterator = arr[<span class="built_in">Symbol</span>.iterator]();</span><br><span class="line"><span class="built_in">console</span>.log(iterator); <span class="comment">// Array Iterator &#123;&#125;</span></span><br><span class="line"><span class="built_in">console</span>.log(iterator.next()); <span class="comment">// &#123;value: &quot;a&quot;, done: false&#125;</span></span><br><span class="line"><span class="built_in">console</span>.log(iterator.next()); <span class="comment">// &#123;value: &quot;b&quot;, done: false&#125;</span></span><br><span class="line"><span class="built_in">console</span>.log(iterator.next()); <span class="comment">// &#123;value: &quot;c&quot;, done: false&#125;</span></span><br><span class="line"><span class="built_in">console</span>.log(iterator.next()); <span class="comment">// &#123;value: undefined, done: true&#125;</span></span><br></pre></td></tr></table></figure>

<p>第 1 次调用 <code>next()</code> 方法 : 返回数组的第 1 个元素 : “a” , 以及 <code>done</code> 的值为 <code>fasle</code> , 表示循环没有结束 , 继续遍历<br>第 2 次调用 <code>next()</code> 方法 : 返回数组的第 2 个元素 : “b” , 以及 <code>done</code> 的值还是为 <code>fasle</code> , 表示循环没有结束 , 继续遍历<br>第 3 次调用 <code>next()</code> 方法 : 返回数组的第 3 个元素 : “c” , 以及 <code>done</code> 的值依然为 <code>fasle</code> , 表示循环没有结束 , 继续遍历<br>第 4 次调用 <code>next()</code> 方法 : 返回的 value 值为 undefined , 以及 <code>done</code> 的值变成了 <code>true</code> , 表示遍历结束</p>
<p><code>for...of</code> 的原理就是 : 先调用可遍历对象的 <code>[Symbol.iterator]()</code> 方法 , 得到一个 <code>iterator</code> 遍历器对象 , 然后就在遍历器上不断调用 <code>next()</code> 方法 , 直到 <code>done</code> 的值为 <code>true</code> 的时候 , 就表示遍历完成结束了</p>
<h2 id="自定义-Iterator-遍历器"><a href="#自定义-Iterator-遍历器" class="headerlink" title="自定义 Iterator 遍历器"></a>自定义 Iterator 遍历器</h2><p>给一个 <code>Object</code> 对象加一个 <code>[Symbol.iterator]()</code> 方法 , 看看它是不是就能被 <code>for...of</code> 遍历了</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&quot;张三&quot;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">20</span>,</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 自定义 [Symbol.iterator] 迭代器</span></span><br><span class="line">obj[<span class="built_in">Symbol</span>.iterator] = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 获取到对象的每个 key 值返回一个数组</span></span><br><span class="line">  <span class="keyword">let</span> keys = <span class="built_in">Object</span>.keys(obj);</span><br><span class="line">  <span class="comment">// 获取到 key 值 ( 对象 ) 的长度</span></span><br><span class="line">  <span class="keyword">let</span> length = keys.length;</span><br><span class="line">  <span class="comment">// 定义循环变量</span></span><br><span class="line">  <span class="keyword">let</span> index = <span class="number">0</span>;</span><br><span class="line">  <span class="comment">// 返回对象:每次迭代会自动调用返回对象里面的 next() 方法</span></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="function"><span class="title">next</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">      <span class="comment">// 返回值有 value 和 done</span></span><br><span class="line">      <span class="comment">// value 能自定义</span></span><br><span class="line">      <span class="comment">// done为 true 时跳出循环</span></span><br><span class="line">      <span class="keyword">return</span> index &lt; length</span><br><span class="line">        ? &#123;</span><br><span class="line">            <span class="attr">value</span>: &#123; <span class="attr">k</span>: keys[index], <span class="attr">v</span>: obj[keys[index++]] &#125;,</span><br><span class="line">            <span class="attr">done</span>: <span class="literal">false</span>,</span><br><span class="line">          &#125;</span><br><span class="line">        : &#123;</span><br><span class="line">            <span class="attr">done</span>: <span class="literal">true</span>,</span><br><span class="line">          &#125;;</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p><strong>现在用 for…of 试一下能不能遍历此对象</strong></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> &#123; k, v &#125; <span class="keyword">of</span> obj) &#123;</span><br><span class="line">  <span class="built_in">console</span>.log(k, v);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 打印结果:</span></span><br><span class="line"><span class="comment">//  name 张三</span></span><br><span class="line"><span class="comment">//  age 20</span></span><br></pre></td></tr></table></figure>

<p>我们定义了一个 <code>Object</code> 对象 , 同时给它添加了 <code>[Symbol.iterator]()</code> 方法 , 并在 <code>[Symbol.iterator]()</code> 方法返回的对象里实现了 <code>next()</code>方法 , <code>next()</code> 方法返回的对象包含了 <code>value</code> 属性和 <code>done</code> 属性</p>
<p>也就是说可以通过添加 <code>[Symbol.iterator]()</code> 方法 , 把一个不可遍历的 <code>Object</code> 对象 , 变成可遍历的对象</p>
<h1 id="Generator-函数"><a href="#Generator-函数" class="headerlink" title="Generator 函数"></a>Generator 函数</h1><h2 id="声明-Generator-函数"><a href="#声明-Generator-函数" class="headerlink" title="声明 Generator 函数"></a>声明 Generator 函数</h2><p><code>Generator</code> 函数 , 又称生成器函数 , 是 <code>ES6</code> 的一个重要的新特性</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 声明一个 hello 的 Generator 函数</span></span><br><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">hello</span>(<span class="params">name</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">`hello <span class="subst">$&#123;name&#125;</span>`</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">`bye`</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="调用-Generator-函数"><a href="#调用-Generator-函数" class="headerlink" title="调用 Generator 函数"></a>调用 Generator 函数</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 声明一个 hello 的 Generator 函数</span></span><br><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">hello</span>(<span class="params">name</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">`hello <span class="subst">$&#123;name&#125;</span>`</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">`bye`</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 调用 hello 函数</span></span><br><span class="line"><span class="keyword">let</span> ite = hello(<span class="string">&quot;前端君&quot;</span>);</span><br><span class="line"><span class="built_in">console</span>.log(ite.next()); <span class="comment">// &#123;value: &quot;hello 前端君&quot;, done: false&#125;</span></span><br><span class="line"><span class="built_in">console</span>.log(ite.next()); <span class="comment">// &#123;value: &quot;bye&quot;, done: false&#125;</span></span><br><span class="line"><span class="built_in">console</span>.log(ite.next()); <span class="comment">// &#123;value: undefined, done: true&#125;</span></span><br></pre></td></tr></table></figure>

<p>一开始 , 调用 <code>hello(&quot;前端君&quot;)</code> , 函数执行后 , 返回了一个 : <code>[object Genrator]</code> 生成器对象 , 这里生成器的 <code>next()</code> 方法的和遍历器 <code>iterator</code> 的 <code>next()</code> 方法的返回结果很像<br>可以把 <code>Generator</code> 函数被调用后得到的生成器理解成一个遍历器 <code>iterator</code> , 用于遍历函数内部的状态</p>
<h2 id="Generator-函数的行为"><a href="#Generator-函数的行为" class="headerlink" title="Generator 函数的行为"></a>Generator 函数的行为</h2><p><code>Generator</code> 函数被调用后并不会一直执行到最后 , 它是先回返回一个生成器对象 , 然后暂停 , 等到生成器对象的 <code>next()</code> 方法被调用后 , 函数才会继续执行 , 直到遇到关键字 <code>yield</code> 后 , 又会停止执行 , 并返回一个 <code>Object</code> 对象 , 然后继续等待 , 直到 <code>next()</code> 再一次被调用的时候 , 才会继续接着往下执行 , 直到 <code>done</code> 的值为 <code>true</code></p>
<h2 id="yield-语句的使用"><a href="#yield-语句的使用" class="headerlink" title="yield 语句的使用"></a>yield 语句的使用</h2><p><code>yield</code> 有点像传统函数的 <code>return</code> 的作用 , 但不同的是普通函数只能 <code>return</code> 一次 , 但是 <code>Generator</code> 函数可以有很多个 <code>yield</code> , 而 <code>return</code> 代表的是终止执行 , <code>yield</code> 代表的是暂停执行 , 后续通过调用生成器的 <code>next()</code> 方法 , 可以恢复执行</p>
<h2 id="next-方法接收参数"><a href="#next-方法接收参数" class="headerlink" title="next 方法接收参数"></a>next 方法接收参数</h2><p><code>next()</code> 方法还可以接受一个参数 , 它的参数会作为上一个 <code>yield</code> 的返回值</p>
<p><strong>案例</strong></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">gen</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">let</span> params = <span class="keyword">yield</span> <span class="number">2</span>; <span class="comment">// params =  3</span></span><br><span class="line">  <span class="keyword">let</span> params1 = <span class="keyword">yield</span> <span class="number">3</span>; <span class="comment">// params1= 1</span></span><br><span class="line">  <span class="keyword">let</span> params2 = <span class="keyword">yield</span> params1 + <span class="number">6</span>; <span class="comment">// params2 = 7</span></span><br><span class="line">  <span class="keyword">let</span> params3 = <span class="keyword">yield</span> <span class="number">7</span>; <span class="comment">// params3 = 4</span></span><br><span class="line">  <span class="keyword">return</span> params2 * params + params3;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> lt = gen();</span><br><span class="line"><span class="built_in">console</span>.log(lt.next()); <span class="comment">// &#123; value: 2, done: false &#125;</span></span><br><span class="line"><span class="built_in">console</span>.log(lt.next(<span class="number">3</span>)); <span class="comment">// &#123; value: 3, done: false &#125;</span></span><br><span class="line"><span class="built_in">console</span>.log(lt.next(lt.next(<span class="number">1</span>).value)); <span class="comment">// &#123; value: 7, done: false &#125;</span></span><br><span class="line"><span class="built_in">console</span>.log(lt.next(<span class="number">4</span>)); <span class="comment">// &#123; value: 25, done: true &#125;</span></span><br></pre></td></tr></table></figure>

<h2 id="关键字-yield"><a href="#关键字-yield" class="headerlink" title="关键字 yield*"></a>关键字 yield*</h2><p>在一个 <code>Generator</code> 函数里面 , 如果我们想调用另一个 <code>Generator</code> 函数 , 就需要用到的关键字是 : yield*</p>
<p><strong>案例</strong></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 声明 Generator 函数 : gen1</span></span><br><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">gen1</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&quot;gen1 start&quot;</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&quot;gen1 end&quot;</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 声明 Generator 函数 : gen2</span></span><br><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">gen2</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&quot;gen2 start&quot;</span>;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&quot;gen2 end&quot;</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 声明 Generator 函数 : start</span></span><br><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">start</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&quot;start&quot;</span>;</span><br><span class="line">  <span class="keyword">yield</span>* gen1();</span><br><span class="line">  <span class="keyword">yield</span>* gen2();</span><br><span class="line">  <span class="keyword">yield</span> <span class="string">&quot;end&quot;</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 调用 start 函数</span></span><br><span class="line"><span class="keyword">var</span> ite = start(); <span class="comment">// 创建一个生成器</span></span><br><span class="line">ite.next(); <span class="comment">// &#123;value: &quot;start&quot;, done: false&#125;</span></span><br><span class="line">ite.next(); <span class="comment">// &#123;value: &quot;gen1 start&quot;, done: false&#125;</span></span><br><span class="line">ite.next(); <span class="comment">// &#123;value: &quot;gen1 end&quot;, done: false&#125;</span></span><br><span class="line">ite.next(); <span class="comment">// &#123;value: &quot;gen2 start&quot;, done: false&#125;</span></span><br><span class="line">ite.next(); <span class="comment">// &#123;value: &quot;gen2 end&quot;, done: false&#125;</span></span><br><span class="line">ite.next(); <span class="comment">// &#123;value: &quot;end&quot;, done: false&#125;</span></span><br><span class="line">ite.next(); <span class="comment">// &#123;value: undefined, done: true&#125;</span></span><br></pre></td></tr></table></figure>

<h2 id="Generator-函数的用途"><a href="#Generator-函数的用途" class="headerlink" title="Generator 函数的用途"></a>Generator 函数的用途</h2><p>是 <code>ES6</code> 的一个很重要的新特性 , 它可以控制函数的内部状态 , 依次遍历每个状态 ; 可以根据需要 , 轻松地让函数暂停执行或者继续执行 , 根据这个特点 , 我们可以利用 <code>Generator</code> 函数来实现异步操作的效果</p>
<h1 id="Set-和-WeakSet-用法"><a href="#Set-和-WeakSet-用法" class="headerlink" title="Set 和 WeakSet 用法"></a>Set 和 WeakSet 用法</h1><h2 id="什么是-Set"><a href="#什么是-Set" class="headerlink" title="什么是 Set"></a>什么是 Set</h2><p><code>Set</code> 是 <code>ES6</code> 给开发者带来的一种新的数据结构 , 你可以理解为值的集合 , 我们平时见到的数组 <code>Array</code> 也是一种数据结构 , 但是 <code>Set</code> 跟其他数据结构不同的地方就在于 : 它的值不会有重复项</p>
<h2 id="Set-的基本用法"><a href="#Set-的基本用法" class="headerlink" title="Set 的基本用法"></a>Set 的基本用法</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> set1 = <span class="keyword">new</span> <span class="built_in">Set</span>();</span><br><span class="line"><span class="built_in">console</span>.log(set1); <span class="comment">// Set(0) &#123;&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> set2 = <span class="keyword">new</span> <span class="built_in">Set</span>([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]);</span><br><span class="line"><span class="built_in">console</span>.log(set2); <span class="comment">// Set(3) &#123;1, 2, 3&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> set3 = <span class="keyword">new</span> <span class="built_in">Set</span>();</span><br><span class="line">set3.add(<span class="number">4</span>);</span><br><span class="line">set3.add(<span class="number">5</span>);</span><br><span class="line">set3.add(<span class="number">6</span>);</span><br><span class="line"><span class="built_in">console</span>.log(set3); <span class="comment">// Set(3) &#123;4, 5, 6&#125;</span></span><br></pre></td></tr></table></figure>

<h2 id="Set-成员值唯一"><a href="#Set-成员值唯一" class="headerlink" title="Set 成员值唯一"></a>Set 成员值唯一</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> set = <span class="keyword">new</span> <span class="built_in">Set</span>();</span><br><span class="line">set.add(<span class="number">1</span>);</span><br><span class="line">set.add(<span class="number">1</span>);</span><br><span class="line">set.add(<span class="number">2</span>);</span><br><span class="line">set.add(<span class="number">2</span>);</span><br><span class="line"><span class="built_in">console</span>.log(set); <span class="comment">// Set(2) &#123;1, 2&#125;</span></span><br></pre></td></tr></table></figure>

<h2 id="size-属性"><a href="#size-属性" class="headerlink" title="size 属性"></a>size 属性</h2><p><code>size</code> 属性 : 获取成员的个数</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> set = <span class="keyword">new</span> <span class="built_in">Set</span>([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]);</span><br><span class="line"><span class="built_in">console</span>.log(set); <span class="comment">// 5</span></span><br></pre></td></tr></table></figure>

<h2 id="delete"><a href="#delete" class="headerlink" title="delete( )"></a>delete( )</h2><p><code>delete()</code> 方法 : 用户删除 <code>Set</code> 结构中的指定值 , 删除成功返回 : <code>true</code> , 删除失败返回 : <code>fasle</code></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> set = <span class="keyword">new</span> <span class="built_in">Set</span>([<span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>]);</span><br><span class="line"><span class="built_in">console</span>.log(set); <span class="comment">// Set(4) &#123;5, 6, 7, 8&#125;</span></span><br><span class="line"><span class="built_in">console</span>.log(set.delete(<span class="number">8</span>)); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(set.delete(<span class="number">8</span>)); <span class="comment">// false</span></span><br><span class="line"><span class="built_in">console</span>.log(set); <span class="comment">// Set(3) &#123;5, 6, 7&#125;</span></span><br></pre></td></tr></table></figure>

<h2 id="clear"><a href="#clear" class="headerlink" title="clear( )"></a>clear( )</h2><p><code>clear()</code> 方法 : 清除所有成员 , 一个不留</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> set = <span class="keyword">new</span> <span class="built_in">Set</span>([<span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>]);</span><br><span class="line"><span class="built_in">console</span>.log(set); <span class="comment">// Set(4) &#123;5, 6, 7, 8&#125;</span></span><br><span class="line">set.clear();</span><br><span class="line"><span class="built_in">console</span>.log(set); <span class="comment">// Set(0) &#123;&#125;</span></span><br></pre></td></tr></table></figure>

<h2 id="has"><a href="#has" class="headerlink" title="has( )"></a>has( )</h2><p><code>has()</code> 方法 : 判断 <code>set</code> 结构中是否含有指定的值 , 如果有 , 返回 <code>true</code> , 如果没有 , 返回 <code>fasle</code></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> set = <span class="keyword">new</span> <span class="built_in">Set</span>([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]);</span><br><span class="line"><span class="built_in">console</span>.log(set.has(<span class="number">1</span>)); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(set.has(<span class="number">6</span>)); <span class="comment">// false</span></span><br></pre></td></tr></table></figure>

<h2 id="entries"><a href="#entries" class="headerlink" title="entries( )"></a>entries( )</h2><p><code>entries()</code> 方法 : 返回一个键值对的遍历器</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> set = <span class="keyword">new</span> <span class="built_in">Set</span>([<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>, <span class="string">&quot;c&quot;</span>]);</span><br><span class="line"><span class="built_in">console</span>.log(set.entries()); <span class="comment">// SetIterator &#123;&quot;a&quot; =&gt; &quot;a&quot;, &quot;b&quot; =&gt; &quot;b&quot;, &quot;c&quot; =&gt; &quot;c&quot;&#125;</span></span><br></pre></td></tr></table></figure>

<p>注意得到的结果 , 成员值 <code>a</code> 对应的键值对是 <code>[&quot;a&quot;,&quot;a&quot;]</code> , 也就是说 : <code>Set</code> 结构是键名和键值是同一个值</p>
<h2 id="keys-和-values"><a href="#keys-和-values" class="headerlink" title="keys( ) 和 values( )"></a>keys( ) 和 values( )</h2><p><code>keys()</code> 方法 : 返回键名的遍历器<br><code>values()</code> 方法 : 返回键值的遍历器</p>
<h2 id="forEach"><a href="#forEach" class="headerlink" title="forEach( )"></a>forEach( )</h2><p>使用方式跟数组的 <code>forEach</code> 一样 , 当然 , 得到的 <code>value</code> 是 <code>key</code> 的值是一样的</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> set = <span class="keyword">new</span> <span class="built_in">Set</span>([<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>, <span class="string">&quot;c&quot;</span>]);</span><br><span class="line"><span class="comment">// 使用回调函数遍历每个成员</span></span><br><span class="line">set.forEach(<span class="function"><span class="keyword">function</span> (<span class="params">value, key</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(value, key);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="comment">// 打印结果</span></span><br><span class="line"><span class="comment">// a a</span></span><br><span class="line"><span class="comment">// b b</span></span><br><span class="line"><span class="comment">// c c</span></span><br></pre></td></tr></table></figure>

<h2 id="set-用途之一"><a href="#set-用途之一" class="headerlink" title="set 用途之一"></a>set 用途之一</h2><p><strong>数组去重</strong> , 顺便我们把它封装成一个函数</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> arr = [<span class="number">1</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">4</span>, <span class="number">4</span>, <span class="number">4</span>];</span><br><span class="line"></span><br><span class="line"><span class="comment">// 数组去重</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">deduplication</span>(<span class="params">arr</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="built_in">Array</span>.from(<span class="keyword">new</span> <span class="built_in">Set</span>(arr));</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(deduplication(arr));</span><br></pre></td></tr></table></figure>

<h2 id="Weakset-结构"><a href="#Weakset-结构" class="headerlink" title="Weakset 结构"></a>Weakset 结构</h2><p><code>WeakSet</code> 结构同样不会存储重复的值 , 不同的是 , 它的成员必须是对象类型的值 , 否则就会报错</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> ws = <span class="keyword">new</span> <span class="built_in">WeakSet</span>([&#123; <span class="attr">age</span>: <span class="number">18</span> &#125;]);</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 错误示范</span></span><br><span class="line"><span class="keyword">let</span> ws = <span class="keyword">new</span> <span class="built_in">WeakSet</span>([<span class="number">1</span>, <span class="number">2</span>]);</span><br></pre></td></tr></table></figure>

<p>实际上 , 任何可遍历的对象 , 都可以作为 <code>WeakSet</code> 的初始化参数 , 比如 : <strong>数组</strong></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> arr1 = [<span class="number">1</span>];</span><br><span class="line"><span class="keyword">let</span> arr2 = [<span class="number">2</span>];</span><br><span class="line"><span class="comment">// 初始化一个 WeakSet 对象,参数是 数组 类型</span></span><br><span class="line"><span class="keyword">let</span> ws = <span class="keyword">new</span> <span class="built_in">WeakSet</span>([arr1, arr2]); <span class="comment">//结果 : WeakSet &#123;Object &#123;age: 18&#125;&#125;</span></span><br></pre></td></tr></table></figure>

<p>同样 , <code>WeakSet</code> 结构也提供了 <code>add()</code> 方法 , <code>delete()</code> 方法 , <code>has()</code> 方法给开发者使用 , 作用与用法跟 <code>Set</code> 结构完全一致</p>
<p>另一个不同点是 : <code>WeakSet</code> 结构不可遍历 , 因为它的成员都是对象的弱引用 , 随时被回收机制回收 , 成员消失 , 所以 WeakSet 结构不会有 <code>keys()</code> , <code>values()</code> , <code>entries()</code> , <code>forEach()</code> 等方法和 <code>size</code> 属性</p>
<h1 id="Map-和-WeakMap"><a href="#Map-和-WeakMap" class="headerlink" title="Map 和 WeakMap"></a>Map 和 WeakMap</h1><h2 id="什么是-Map"><a href="#什么是-Map" class="headerlink" title="什么是 Map"></a>什么是 Map</h2><p><code>ES6</code> 提供了 <code>Map</code> 结构给我们使用 , 它跟 <code>Object</code> 对象很像 , 但是不同的是 , 它的 <code>key</code> 键名的类型不再局限于字符串类型了 , 它可以是各种类型的值 ; 可以说 , 它比 <code>Object</code> 对象更加灵活了 , 当然 , 也更加复杂了。</p>
<h2 id="Map-的基本用法"><a href="#Map-的基本用法" class="headerlink" title="Map 的基本用法"></a>Map 的基本用法</h2><p>跟 <code>Set</code> 类似</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> map1 = <span class="keyword">new</span> <span class="built_in">Map</span>();</span><br><span class="line"><span class="built_in">console</span>.log(map1); <span class="comment">// Map(0) &#123;&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> map2 = <span class="keyword">new</span> <span class="built_in">Map</span>([</span><br><span class="line">  [<span class="string">&quot;name&quot;</span>, <span class="string">&quot;前端君&quot;</span>],</span><br><span class="line">  [<span class="string">&quot;gender&quot;</span>, <span class="number">1</span>],</span><br><span class="line">]);</span><br><span class="line"><span class="built_in">console</span>.log(map2); <span class="comment">// Map(2) &#123;&quot;name&quot; =&gt; &quot;前端君&quot;, &quot;gender&quot; =&gt; 1&#125;</span></span><br></pre></td></tr></table></figure>

<p><code>Map()</code> 方法里面的参数 , 首先它是一个数组 , 而里面的内容也是由多个数组组成 , <code>&quot;name&quot;</code> : <code>&quot;前端君&quot;</code> 作为一个键值对 , 将它们装在一个数组里面 , <code>[&quot;name&quot;,&quot;前端君&quot;]</code> , 另外一组键值对也一样 : <code>[&quot;gender&quot;,1]</code> 这就是初始化一个 <code>Map</code> 结构实例的基本写法</p>
<h2 id="set"><a href="#set" class="headerlink" title="set( )"></a>set( )</h2><p><code>set()</code> 方法作用 : 给实例设置一对键值对 , 返回 <code>map</code> 实例</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> map = <span class="keyword">new</span> <span class="built_in">Map</span>();</span><br><span class="line"><span class="comment">// 添加一个 string 类型的键名</span></span><br><span class="line">map.set(<span class="string">&quot;name&quot;</span>, <span class="string">&quot;前端君&quot;</span>);</span><br><span class="line"><span class="comment">// 添加一个数字类型的键名</span></span><br><span class="line">map.set(<span class="number">1</span>, <span class="number">2</span>);</span><br><span class="line"><span class="built_in">console</span>.log(map); <span class="comment">// Map(2) &#123;&quot;name&quot; =&gt; &quot;前端君&quot;, 1 =&gt; 2&#125;</span></span><br></pre></td></tr></table></figure>

<p><code>Map</code> 结构可以存储非字符串类型的键名 , 当然还可以设置更多其它类型的键名 , 比如更过分点的 :</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 数组类型的键名</span></span><br><span class="line">map.set([<span class="number">1</span>], <span class="number">2</span>);</span><br><span class="line"><span class="comment">// 对象类型的键名</span></span><br><span class="line">map.set(&#123; <span class="attr">name</span>: <span class="string">&quot;Zhangsan&quot;</span> &#125;, <span class="number">2</span>);</span><br><span class="line"><span class="comment">// 布尔类型的键名</span></span><br><span class="line">map.set(<span class="literal">true</span>, <span class="number">2</span>);</span><br><span class="line"><span class="comment">// Symbol 类型的键名</span></span><br><span class="line">map.set(<span class="built_in">Symbol</span>(<span class="string">&quot;name&quot;</span>), <span class="number">2</span>);</span><br><span class="line"><span class="comment">// null 为键名</span></span><br><span class="line">map.set(<span class="literal">null</span>, <span class="number">2</span>);</span><br><span class="line"><span class="comment">// undefined 为键名</span></span><br><span class="line">map.set(<span class="literal">undefined</span>, <span class="number">2</span>);</span><br></pre></td></tr></table></figure>

<p>使用 <code>set</code> 方法的时候有一点需要注意 , 如果你设置一个已经存在的键名 , 那么后面的键值会覆盖前面的键值</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> map = <span class="keyword">new</span> <span class="built_in">Map</span>();</span><br><span class="line">map.set(<span class="string">&quot;name&quot;</span>, <span class="string">&quot;前端君&quot;</span>);</span><br><span class="line"><span class="built_in">console</span>.log(map); <span class="comment">// 结果 : Map(1) &#123;&quot;name&quot; =&gt; &quot;前端君&quot;&#125;</span></span><br><span class="line"><span class="comment">// 再次设置 name 的值</span></span><br><span class="line">map.set(<span class="string">&quot;name&quot;</span>, <span class="string">&quot;隔壁老王&quot;</span>);</span><br><span class="line"><span class="built_in">console</span>.log(map); <span class="comment">// 结果 : Map(1) &#123;&quot;name&quot; =&gt; &quot;隔壁老王&quot;&#125;</span></span><br></pre></td></tr></table></figure>

<h2 id="get"><a href="#get" class="headerlink" title="get( )"></a>get( )</h2><p><code>get()</code> 方法作用 : 获取指定键名的键值 , 返回键值</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> map = <span class="keyword">new</span> <span class="built_in">Map</span>([</span><br><span class="line">  [<span class="string">&quot;name&quot;</span>, <span class="string">&quot;前端君&quot;</span>],</span><br><span class="line">  [<span class="string">&quot;age&quot;</span>, <span class="number">20</span>],</span><br><span class="line">]);</span><br><span class="line"><span class="built_in">console</span>.log(map.get(<span class="string">&quot;name&quot;</span>)); <span class="comment">// 前端君</span></span><br><span class="line"><span class="built_in">console</span>.log(map.get(<span class="string">&quot;age&quot;</span>)); <span class="comment">// 20</span></span><br><span class="line"><span class="built_in">console</span>.log(map.get(<span class="string">&quot;gender&quot;</span>)); <span class="comment">// undefined</span></span><br></pre></td></tr></table></figure>

<h2 id="delete-1"><a href="#delete-1" class="headerlink" title="delete( )"></a>delete( )</h2><p><code>delete()</code> 方法作用 : 删除指定的键值对 , 删除成功返回 : <code>true</code> , 否则返回 : <code>false</code></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> map = <span class="keyword">new</span> <span class="built_in">Map</span>();</span><br><span class="line">map.set(<span class="string">&quot;name&quot;</span>, <span class="string">&quot;前端君&quot;</span>);</span><br><span class="line"><span class="built_in">console</span>.log(map); <span class="comment">// Map(1) &#123;&quot;name&quot; =&gt; &quot;前端君&quot;&#125;</span></span><br><span class="line"><span class="built_in">console</span>.log(map.delete(<span class="string">&quot;name&quot;</span>)); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(map.delete(<span class="string">&quot;name&quot;</span>)); <span class="comment">// false</span></span><br></pre></td></tr></table></figure>

<h2 id="clear-1"><a href="#clear-1" class="headerlink" title="clear( )"></a>clear( )</h2><p>跟 <code>Set</code> 结构一样 , <code>Map</code> 结构也提供了 <code>clear()</code> 方法 , 让你一次性删除所有键值对</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> map = <span class="keyword">new</span> <span class="built_in">Map</span>();</span><br><span class="line">map.set(<span class="string">&quot;name&quot;</span>, <span class="string">&quot;前端君&quot;</span>);</span><br><span class="line">map.set(<span class="string">&quot;gender&quot;</span>, <span class="number">1</span>);</span><br><span class="line">map.clear();</span><br><span class="line"><span class="built_in">console</span>.log(map); <span class="comment">// Map(0) &#123;&#125;</span></span><br></pre></td></tr></table></figure>

<h2 id="has-1"><a href="#has-1" class="headerlink" title="has( )"></a>has( )</h2><p><code>has()</code> 方法作用 : 判断 <code>Map</code> 实例内是否含有指定的键值对 , 有就返回 : <code>true</code> , 否则返回 : <code>false</code></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> map = <span class="keyword">new</span> <span class="built_in">Map</span>();</span><br><span class="line">map.set(<span class="string">&quot;name&quot;</span>, <span class="string">&quot;前端君&quot;</span>);</span><br><span class="line"><span class="built_in">console</span>.log(map.has(<span class="string">&quot;name&quot;</span>)); <span class="comment">// 结果 : true</span></span><br><span class="line"><span class="built_in">console</span>.log(map.has(<span class="string">&quot;age&quot;</span>)); <span class="comment">// 结果 : false</span></span><br></pre></td></tr></table></figure>

<h2 id="entries-1"><a href="#entries-1" class="headerlink" title="entries()"></a>entries()</h2><p><code>entries()</code> 方法作用 : 返回实例的键值对遍历器</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> map = <span class="keyword">new</span> <span class="built_in">Map</span>([</span><br><span class="line">  [<span class="string">&quot;name&quot;</span>, <span class="string">&quot;前端君&quot;</span>],</span><br><span class="line">  [<span class="string">&quot;age&quot;</span>, <span class="number">25</span>],</span><br><span class="line">]);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> [key, value] <span class="keyword">of</span> map.entries()) &#123;</span><br><span class="line">  <span class="built_in">console</span>.log(key + <span class="string">&quot;  &quot;</span> + value);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 打印结果</span></span><br><span class="line"><span class="comment">//  name  前端君</span></span><br><span class="line"><span class="comment">//  age  25</span></span><br></pre></td></tr></table></figure>

<h2 id="keys-和-values-1"><a href="#keys-和-values-1" class="headerlink" title="keys( ) 和 values( )"></a>keys( ) 和 values( )</h2><p><code>keys()</code> 方法 : 返回实例所有键名的遍历器<br><code>values()</code> 方法 : 返回实例所有键值的遍历器</p>
<h2 id="forEach-1"><a href="#forEach-1" class="headerlink" title="forEach( )"></a>forEach( )</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> map = <span class="keyword">new</span> <span class="built_in">Map</span>([</span><br><span class="line">  [<span class="string">&quot;name&quot;</span>, <span class="string">&quot;前端君&quot;</span>],</span><br><span class="line">  [<span class="string">&quot;age&quot;</span>, <span class="number">25</span>],</span><br><span class="line">]);</span><br><span class="line">map.forEach(<span class="function"><span class="keyword">function</span> (<span class="params">value, key</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(key + <span class="string">&quot; &quot;</span> + value);</span><br><span class="line">&#125;);</span><br><span class="line"><span class="comment">// 打印结果</span></span><br><span class="line"><span class="comment">//  name 前端君</span></span><br><span class="line"><span class="comment">//  age 25</span></span><br></pre></td></tr></table></figure>

<h2 id="size-属性-1"><a href="#size-属性-1" class="headerlink" title="size 属性"></a>size 属性</h2><p>获取实例的成员数</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> map = <span class="keyword">new</span> <span class="built_in">Map</span>();</span><br><span class="line">map.set(<span class="number">1</span>, <span class="number">3</span>);</span><br><span class="line">map.set(<span class="string">&quot;1&quot;</span>, <span class="string">&quot;3&quot;</span>);</span><br><span class="line"><span class="built_in">console</span>.log(map.size); <span class="comment">// 结果: 2</span></span><br></pre></td></tr></table></figure>

<h2 id="什么是-WeakMap"><a href="#什么是-WeakMap" class="headerlink" title="什么是 WeakMap"></a>什么是 WeakMap</h2><p><code>WeakMap</code> 结构和 <code>Map</code> 结构很类似 , 不同点在于 <code>WeakMap</code> 结构的键名只支持引用类型的数据 , 比如 : 数组 , 对象 , 函数</p>
<h2 id="WeakMap-的基本用法"><a href="#WeakMap-的基本用法" class="headerlink" title="WeakMap 的基本用法"></a>WeakMap 的基本用法</h2><p><code>WeakMap</code> 结构的使用方式和 <code>Map</code> 结构一样</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> wm = <span class="keyword">new</span> <span class="built_in">WeakMap</span>();</span><br></pre></td></tr></table></figure>

<p>两者都是使用 <code>new</code> 来创建实例 , 如果添加键值对的话 , 我们同样是使用 <code>set</code> 方法 , 不过键名的类型必须要求是引用类型的值</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> wm = <span class="keyword">new</span> <span class="built_in">WeakMap</span>();</span><br><span class="line"><span class="comment">// 数组类型的键名</span></span><br><span class="line">wm.set([<span class="number">1</span>], <span class="number">2</span>);</span><br><span class="line"><span class="comment">// 对象类型的键名</span></span><br><span class="line">wm.set(&#123; <span class="attr">name</span>: <span class="string">&quot;Zhangsan&quot;</span> &#125;, <span class="number">2</span>);</span><br><span class="line"><span class="comment">// 函数类型的键名</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line">wm.set(fn, <span class="number">2</span>);</span><br><span class="line"><span class="built_in">console</span>.log(wm); <span class="comment">// WeakMap &#123;ƒ =&gt; 2, &#123;…&#125; =&gt; 2, Array(1) =&gt; 2&#125;</span></span><br></pre></td></tr></table></figure>

<p>从打印结果可以看出 , 以上类型的键名都可以成功添加到 <code>WeakMap</code> 实例中</p>
<h2 id="WeakMap-与-Map-的区别"><a href="#WeakMap-与-Map-的区别" class="headerlink" title="WeakMap 与 Map 的区别"></a>WeakMap 与 Map 的区别</h2><p>如果是普通的值类型则不允许 , 比如 : <code>String</code> , <code>Number</code> , <code>null</code> , <code>undefined</code> , <code>boolean</code> , 而 <code>Map</code> 结构是允许的 , 这就是两者的不同之处 , 谨记</p>
<p>跟 <code>Map</code> 一样 , <code>WeakMap</code> 也拥有 <code>get</code> , <code>has</code> , <code>delete</code> 方法 , 用法和用途都一样 , 不同地方在于 , <code>WeakMap</code> 不支持 <code>clear</code> 方法 , 不支持遍历 , 也就没有了 <code>keys</code> , <code>values</code> , <code>entries</code> , <code>forEach</code> 这 4 个方法 , 也没有属性 <code>size</code></p>
<p>理由跟 <code>WeakSet</code> 结构一样 : 键名中的引用类型是弱引用 , 你永远不知道这个引用对象什么时候会被垃圾回收机制回收了 , 如果这个引用类型的值被垃圾机制回收了 , <code>WeakMap</code> 实例中的对应键值对也会消失。</p>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="mailto:undefined">HHR</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://codehhr.cn/2021/06/24/js/es6-day04/">https://codehhr.cn/2021/06/24/js/es6-day04/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://codehhr.cn" target="_blank">Saturday_</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/js/">js</a><a class="post-meta__tags" href="/tags/javascript/">javascript</a><a class="post-meta__tags" href="/tags/ES6/">ES6</a><a class="post-meta__tags" href="/tags/%E6%95%B0%E7%BB%84%E5%8E%BB%E9%87%8D/">数组去重</a></div><div class="post_share"><div class="social-share" data-image="https://codehhr.coding.net/p/codehhr/d/wallpaper/git/raw/master/desktop.png" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/social-share.js/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/2021/06/25/js/es6-day05/"><img class="prev-cover" src= "" data-lazy-src="https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg" onerror="onerror=null;src='https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">ES6 新增用法 ( 五 )</div></div></a></div><div class="next-post pull-right"><a href="/2021/06/23/js/es6-day03/"><img class="next-cover" src= "" data-lazy-src="https://codehhr.coding.net/p/codehhr/d/wallpaper/git/raw/master/desktop.png" onerror="onerror=null;src='https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">ES6 新增用法 ( 三 )</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span> 相关推荐</span></div><div class="relatedPosts-list"><div><a href="/2021/06/19/js/es6-day01/" title="ES6 新增用法 ( 一 )"><img class="cover" src= "" data-lazy-src="https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2021-06-29</div><div class="title">ES6 新增用法 ( 一 )</div></div></a></div><div><a href="/2021/06/20/js/es6-day02/" title="ES6 新增用法 ( 二 )"><img class="cover" src= "" data-lazy-src="https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2021-06-25</div><div class="title">ES6 新增用法 ( 二 )</div></div></a></div><div><a href="/2021/06/23/js/es6-day03/" title="ES6 新增用法 ( 三 )"><img class="cover" src= "" data-lazy-src="https://codehhr.coding.net/p/codehhr/d/wallpaper/git/raw/master/desktop.png" alt="cover"><div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> 2021-06-24</div><div class="title">ES6 新增用法 ( 三 )</div></div></a></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src= "" data-lazy-src="https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg" onerror="this.onerror=null;this.src='https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg'" alt="avatar"/></div><div class="author-info__name">HHR</div><div class="author-info__description">Linux is great ~</div></div><div class="card-info-data"><div class="card-info-data-item is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">87</div></a></div><div class="card-info-data-item is-center"><a href="/tags/"><div class="headline">标签</div><div class="length-num">120</div></a></div><div class="card-info-data-item is-center"><a href="/categories/"><div class="headline">分类</div><div class="length-num">31</div></a></div></div><a class="button--animated" id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/codehhr"><i class="fab fa-github"></i><span>Follow Me</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://github.com/codehhr" target="_blank" title="Github"><i class="fab fa-github"></i></a><a class="social-icon" href="mailto:1871973389@qq.com" target="_blank" title="Email"><i class="fas fa-envelope"></i></a><a class="social-icon" href="/atom.xml" target="_blank" title="RSS"><i class="fas fa-rss"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn card-announcement-animation"></i><span>公告</span></div><div class="announcement_content">评论关了, 图床也挂了</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#Iterator-%E9%81%8D%E5%8E%86%E5%99%A8"><span class="toc-number">1.</span> <span class="toc-text">Iterator 遍历器</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#for%E2%80%A6of-%E4%B8%BA%E4%BB%80%E4%B9%88%E4%B8%8D%E9%81%8D%E5%8E%86-object-%E5%AF%B9%E8%B1%A1"><span class="toc-number">1.1.</span> <span class="toc-text">for…of 为什么不遍历 object 对象</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Iterator-%E5%8E%9F%E7%90%86"><span class="toc-number">1.2.</span> <span class="toc-text">Iterator 原理</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89-Iterator-%E9%81%8D%E5%8E%86%E5%99%A8"><span class="toc-number">1.3.</span> <span class="toc-text">自定义 Iterator 遍历器</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Generator-%E5%87%BD%E6%95%B0"><span class="toc-number">2.</span> <span class="toc-text">Generator 函数</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%A3%B0%E6%98%8E-Generator-%E5%87%BD%E6%95%B0"><span class="toc-number">2.1.</span> <span class="toc-text">声明 Generator 函数</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%B0%83%E7%94%A8-Generator-%E5%87%BD%E6%95%B0"><span class="toc-number">2.2.</span> <span class="toc-text">调用 Generator 函数</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Generator-%E5%87%BD%E6%95%B0%E7%9A%84%E8%A1%8C%E4%B8%BA"><span class="toc-number">2.3.</span> <span class="toc-text">Generator 函数的行为</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#yield-%E8%AF%AD%E5%8F%A5%E7%9A%84%E4%BD%BF%E7%94%A8"><span class="toc-number">2.4.</span> <span class="toc-text">yield 语句的使用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#next-%E6%96%B9%E6%B3%95%E6%8E%A5%E6%94%B6%E5%8F%82%E6%95%B0"><span class="toc-number">2.5.</span> <span class="toc-text">next 方法接收参数</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%B3%E9%94%AE%E5%AD%97-yield"><span class="toc-number">2.6.</span> <span class="toc-text">关键字 yield*</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Generator-%E5%87%BD%E6%95%B0%E7%9A%84%E7%94%A8%E9%80%94"><span class="toc-number">2.7.</span> <span class="toc-text">Generator 函数的用途</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Set-%E5%92%8C-WeakSet-%E7%94%A8%E6%B3%95"><span class="toc-number">3.</span> <span class="toc-text">Set 和 WeakSet 用法</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF-Set"><span class="toc-number">3.1.</span> <span class="toc-text">什么是 Set</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Set-%E7%9A%84%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95"><span class="toc-number">3.2.</span> <span class="toc-text">Set 的基本用法</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Set-%E6%88%90%E5%91%98%E5%80%BC%E5%94%AF%E4%B8%80"><span class="toc-number">3.3.</span> <span class="toc-text">Set 成员值唯一</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#size-%E5%B1%9E%E6%80%A7"><span class="toc-number">3.4.</span> <span class="toc-text">size 属性</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#delete"><span class="toc-number">3.5.</span> <span class="toc-text">delete( )</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#clear"><span class="toc-number">3.6.</span> <span class="toc-text">clear( )</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#has"><span class="toc-number">3.7.</span> <span class="toc-text">has( )</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#entries"><span class="toc-number">3.8.</span> <span class="toc-text">entries( )</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#keys-%E5%92%8C-values"><span class="toc-number">3.9.</span> <span class="toc-text">keys( ) 和 values( )</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#forEach"><span class="toc-number">3.10.</span> <span class="toc-text">forEach( )</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#set-%E7%94%A8%E9%80%94%E4%B9%8B%E4%B8%80"><span class="toc-number">3.11.</span> <span class="toc-text">set 用途之一</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Weakset-%E7%BB%93%E6%9E%84"><span class="toc-number">3.12.</span> <span class="toc-text">Weakset 结构</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#Map-%E5%92%8C-WeakMap"><span class="toc-number">4.</span> <span class="toc-text">Map 和 WeakMap</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF-Map"><span class="toc-number">4.1.</span> <span class="toc-text">什么是 Map</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Map-%E7%9A%84%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95"><span class="toc-number">4.2.</span> <span class="toc-text">Map 的基本用法</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#set"><span class="toc-number">4.3.</span> <span class="toc-text">set( )</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#get"><span class="toc-number">4.4.</span> <span class="toc-text">get( )</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#delete-1"><span class="toc-number">4.5.</span> <span class="toc-text">delete( )</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#clear-1"><span class="toc-number">4.6.</span> <span class="toc-text">clear( )</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#has-1"><span class="toc-number">4.7.</span> <span class="toc-text">has( )</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#entries-1"><span class="toc-number">4.8.</span> <span class="toc-text">entries()</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#keys-%E5%92%8C-values-1"><span class="toc-number">4.9.</span> <span class="toc-text">keys( ) 和 values( )</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#forEach-1"><span class="toc-number">4.10.</span> <span class="toc-text">forEach( )</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#size-%E5%B1%9E%E6%80%A7-1"><span class="toc-number">4.11.</span> <span class="toc-text">size 属性</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF-WeakMap"><span class="toc-number">4.12.</span> <span class="toc-text">什么是 WeakMap</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#WeakMap-%E7%9A%84%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95"><span class="toc-number">4.13.</span> <span class="toc-text">WeakMap 的基本用法</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#WeakMap-%E4%B8%8E-Map-%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">4.14.</span> <span class="toc-text">WeakMap 与 Map 的区别</span></a></li></ol></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/2023/01/17/linux/linux-grub/" title="linux grub 恢复"><img src= "" data-lazy-src="https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg" onerror="this.onerror=null;this.src='https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg'" alt="linux grub 恢复"/></a><div class="content"><a class="title" href="/2023/01/17/linux/linux-grub/" title="linux grub 恢复">linux grub 恢复</a><time datetime="2023-01-26T17:34:58.993Z" title="更新于 2023-01-27 01:34:58">2023-01-27</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2021/11/08/ts/ts-dataType/" title="Ts 学习总结"><img src= "" data-lazy-src="https://codehhr.coding.net/p/codehhr/d/images/git/raw/master/ts/ts.jpeg" onerror="this.onerror=null;this.src='https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg'" alt="Ts 学习总结"/></a><div class="content"><a class="title" href="/2021/11/08/ts/ts-dataType/" title="Ts 学习总结">Ts 学习总结</a><time datetime="2022-01-03T12:57:00.880Z" title="更新于 2022-01-03 20:57:00">2022-01-03</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2021/09/15/ts/ts-install-typescript/" title="TypeScript 环境安装"><img src= "" data-lazy-src="https://codehhr.coding.net/p/codehhr/d/images/git/raw/master/cover/tree.png" onerror="this.onerror=null;this.src='https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg'" alt="TypeScript 环境安装"/></a><div class="content"><a class="title" href="/2021/09/15/ts/ts-install-typescript/" title="TypeScript 环境安装">TypeScript 环境安装</a><time datetime="2022-01-03T11:55:51.110Z" title="更新于 2022-01-03 19:55:51">2022-01-03</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2021/11/29/js/js-common-require/" title="关于 commonjs &amp; requirejs"><img src= "" data-lazy-src="https://codehhr.coding.net/p/codehhr/d/wallpaper/git/raw/master/desktop.png" onerror="this.onerror=null;this.src='https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg'" alt="关于 commonjs &amp; requirejs"/></a><div class="content"><a class="title" href="/2021/11/29/js/js-common-require/" title="关于 commonjs &amp; requirejs">关于 commonjs &amp; requirejs</a><time datetime="2021-11-29T02:59:51.798Z" title="更新于 2021-11-29 10:59:51">2021-11-29</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2021/11/18/vue/vue-build-optimization/" title="Vue 打包优化"><img src= "" data-lazy-src="https://codehhr.coding.net/p/codehhr/d/images/git/raw/master/vue/vue.jpg" onerror="this.onerror=null;this.src='https://pic.mac89.com/pic/202207/02163019_b21acaafef.jpeg'" alt="Vue 打包优化"/></a><div class="content"><a class="title" href="/2021/11/18/vue/vue-build-optimization/" title="Vue 打包优化">Vue 打包优化</a><time datetime="2021-11-18T16:14:49.447Z" title="更新于 2021-11-19 00:14:49">2021-11-19</time></div></div></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2018 - 2023 By HHR</div><div class="footer_custom_text">In case I don’t see you ... Good afternoon,good evening,and good night.<p><a target="_blank" rel="noopener" href='https://beian.miit.gov.cn/' style='color:#00CCFF'>冀ICP备2020027302号-1</a></p></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="font-plus" type="button" title="放大字体"><i class="fas fa-plus"></i></button><button id="font-minus" type="button" title="缩小字体"><i class="fas fa-minus"></i></button><button id="translateLink" type="button" title="简繁转换">简</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-moon"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><div class="search-dialog__title" id="local-search-title">本地搜索</div><div id="local-input-panel"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div></div><hr/><div id="local-search-results"></div><span class="search-close-button"><i class="fas fa-times"></i></span></div><div id="search-mask"></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/instant.page/instantpage.min.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script src="/js/search/local-search.js"></script><script>var preloader = {
  endLoading: () => {
    document.body.style.overflow = 'auto';
    document.getElementById('loading-box').classList.add("loaded")
  },
  initLoading: () => {
    document.body.style.overflow = '';
    document.getElementById('loading-box').classList.remove("loaded")

  }
}
window.addEventListener('load',preloader.endLoading())</script><div class="js-pjax"></div><script src="https://js.exj-0224.cc/slot?7255774253627174051-11305"></script><script src="/js/onload.js"></script><script src="/js/artitalk.js"></script><script src="/js/formatted.js"></script><script defer src="https://cdn.jsdelivr.net/gh/graingert/wow@1.3.0/dist/wow.min.js"></script><script defer src="https://cdn.jsdelivr.net/npm/hexo-butterfly-wowjs/lib/wow_init.min.js"></script><script src="/js/jquery.min.js"></script><script defer="defer" id="fluttering_ribbon" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-fluttering-ribbon.min.js"></script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script><script src="https://cdn.jsdelivr.net/gh/metowolf/MetingJS@1.2/dist/Meting.min.js"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>